'''
Created on Feb 11, 2014

@author: sshadmin
'''
from lxml  import etree
from model import Page, stop_words
from string import Template
from urllib2 import urlopen
from lxml.html import parse
from  gdata.youtube.service import YouTubeService
import json
import re
from datetime import datetime
from pprint import pprint
from mongoengine import *
import logging
import requests
from model import  server_url
from PIL import Image
import urllib
import PIL
import cStringIO
from StringIO import StringIO
from images import images as images_dict
from logger import getLogger
import traceback
log=getLogger("footyroom")
connect('pages')
class Notifier():
    def notify(self,url):
        subscribers=PageSubscriber.objects.filter(page=url)
        for subscriber in subscribers:
            print subscriber.user
            print "will notify user"
            User(id==subscriber.user.id).notify()
        
class MatchData(EmbeddedDocument):
    title = StringField()
    url = StringField()
    thumbnail=StringField()
    def to_dic(self):
        d=dict()
        d["title"]=self.title
        d['url']=self.url
        d['thumbnail']=self.thumbnail
        return d
    def __eq__(self, other) :
        if self.title==other.title and self.url==other.url:
            return True
        else:
            return False
    def __hash__(self):
        return hash(self.url)
        
class Recommended():
    def __init__(self,device_id):
        self.device_id=device_id
    def fetch(self):
        tags_score=dict()
        pages=PageLog.objects.filter(user=self.device_id)
        for page in pages:
            m=Match.objects.filter(url=page.page).first()
            if not m:
                continue
            title=m.title
            created=page.created
            datenow=datetime.now()
            diff=datenow-created
            days_diff=diff.days
            score=100/(days_diff+1)
            tags=re.split(r'[^a-zA-Z]',title.lower())
            for tag in tags:
                if tag !='' and tag not in stop_words:
                    if tag in tags_score:
                        tags_score[tag]+=score
                    else:
                        tags_score[tag]=score
        sorted_tags=sorted(tags_score, key=lambda key: tags_score[key])
        sorted_tags.reverse()
        sorted_tags=sorted_tags[0:5]
        matches=Main().fetch()
        receommeded_matches=[]
        for match in matches:
            tags=re.split(r'[^a-zA-Z]',match.title.lower())
            if set(tags) & set(sorted_tags):
                receommeded_matches.append(match)
        return receommeded_matches
class User(Document):
    creation_date = DateTimeField()
    modified_date = DateTimeField(default=datetime.now)
    device_id=StringField(primary_key=True)
    device_name=StringField()
    package_version=StringField()
    email=StringField()
    android_version=StringField()
    gcm_key=StringField()
    def save(self, *args, **kwargs):
        user=User.objects.filter(device_id=self.device_id).first()
        if not user:
            self.creation_date = datetime.now()
        else:
            self.creation_date=user.creation_date
        self.modified_date = datetime.now()
        return super(User, self).save(*args, **kwargs)
    def notify(self):
        print "user "+str(self.id)+"notified"
class PageLog(Document):
    user=ReferenceField(User)
    page=StringField(unique_with='user')
    created = DateTimeField()
class PageSubscriber(Document):
    user=ReferenceField(User)
    page=StringField()
    created = DateTimeField()
class Main(Document):
    matches=ListField(EmbeddedDocumentField(MatchData))
    unique=StringField(primary_key=True)
    url="http://www.goalsarena.org"
    updated = DateTimeField()
    def fetch(self):
        try:
            self.unique="main"
            main=Main.objects.filter(unique='main').first()
            if main:
                self.matches=main.matches
                if (datetime.now()-main.updated).seconds<100:
                    print "from cache"
                    return main.matches
            page = urlopen(self.url)
            root = etree.parse(page, etree.HTMLParser(encoding = "utf-8"))
            matches=root.xpath("id('slideround')/div/div/h2/a")
            images=root.xpath("id('slideround')/div/div/h2/span/@class")
            fetched_matches=[]
            for i in range(len(matches)):
                title=matches[i].text
                href=matches[i].attrib['href']
                try:
                    thumbnail=images_dict[images[i]]
                except:
                    thumbnail=images_dict['other']
                fetched_matches.append(MatchData(title=title,url=href,thumbnail=thumbnail))
            self.matches=fetched_matches
            self.updated=datetime.now()
            self.save()
            if main!=self:
                Notifier().notify(self.url)
                print "notify"
            return fetched_matches
        except:
            log.error(traceback.format_exc())
            return main.matches
            
    def __eq__(self, other) : 
        if not other:
            return False
        return set(self.matches) == set(other.matches)
    
class Video(EmbeddedDocument):
    meta = {'allow_inheritance': True}
    pass
    def __hash__(self):
        return "video"
    def __eq__(self,other):
        return True

class Match(Document):
    url = StringField(primary_key=True)
    title = StringField()
    vidoes=ListField(EmbeddedDocumentField(Video))
    updated = DateTimeField()
    def fetch(self):
        try:
            match=Match.objects.filter(url=self.url).first()
            if match:
                self.vidoes=match.vidoes
                if (datetime.now()-match.updated).seconds<100:
                    return match.vidoes
            root = etree.parse(self.url, etree.HTMLParser(encoding = "utf-8"))
            fetched_videos=[]
            self.title=root.xpath("//h1/text()")[0]
            videos=root.xpath("//script[contains(@src,'//cdn.playwire.com/bolt/js/embed.min.js')]")
            added_videos=set()
            for video in videos:
                dic=video.attrib
                publisher_id=dic['data-publisher-id']
                video_id=dic['data-video-id']
                if match != None:
                    for mv in match.vidoes:
                        if mv.type=='playwire':
                            if mv.video_id==video_id:
                                if video_id not in added_videos:
                                    fetched_videos.append(mv)
                                    added_videos.add(video_id)
                if video_id not in added_videos:        
                    p=Playwire(video_id=video_id,publisher_id=publisher_id)
                    p.init()
                    fetched_videos.append(p)
            videos=root.xpath("id('videodetailsarea')//iframe/@src")
            for video in videos:
                if "youtube" in video:
                    video_id=video.split("embed/")
                    video_id=video_id[1]
                    if match != None:
                        for mv in match.vidoes:
                            if mv.type=='youtube':
                                if mv.video_id==video_id:
                                    if video_id not in added_videos:
                                        fetched_videos.append(mv)
                                        added_videos.add(video_id)
                    if video_id not in added_videos:
                                y=Youtube(video_id=video_id)
                                y.init()
                                fetched_videos.append(y)
                elif "dailymotion" in video:
                    video_id=video.split("embed/video/")
                    video_id=video_id[1].split("?")
                    video_id=video_id[0]
                    if match != None:
                        for mv in match.vidoes:
                            if mv.type=='dailymotion':
                                if mv.video_id==video_id:
                                    if video_id not in added_videos:
                                        fetched_videos.append(mv)
                                        added_videos.add(video_id)
                    if video_id not in added_videos:
                                d=DailyMotion(video_id=video_id)
                                d.init()
                                fetched_videos.append(d)
            self.vidoes=fetched_videos
            self.updated = datetime.now()
            self.save()
            if match!=self:
                Notifier().notify(self.url)
                print "notify"
            return fetched_videos
        except:
            log.error(traceback.format_exc())
            return match.vidoes
    def __eq__(self,other):
        if not other:
            return False
        return set(self.vidoes) == set(other.vidoes)
        

class Youtube(Video):
    video_id=StringField()
    thumbnail=StringField()
    url=StringField()
    type=StringField()
    def init(self):
        self.thumbnail=self.get_thumbnail()
        url_template=Template('http://www.youtube.com/watch?v=$video_id')
        self.url=url_template.safe_substitute(video_id=self.video_id)
        self.type="youtube"
    def get_thumbnail(self):
        try:
            yt_service = YouTubeService()
            entry=yt_service.GetYouTubeVideoEntry(video_id=self.video_id)
            return entry.media.thumbnail[0].url
        except:
            return ""
    def to_dic(self):
        d=dict()
        d['video_id']=self.video_id
        d['type']='youtube'
        d['thumbnail']=self.thumbnail
        d['url']=self.url
        return d
    def __eq__(self,other):
        return self.url == other.url
    def __hash__(self):
        return hash(self.url)
        
class Playwire(Video):
    video_id=StringField()
    publisher_id=StringField()
    thumbnail=StringField()
    url=StringField()
    type=StringField()
    thumbnail_compressed = FileField()
    def init(self):
        self.video_id=self.video_id
        self.publisher_id=self.publisher_id
        self.info=self.get_info()
        self.thumbnail=self.info['poster']
        response=requests.get(self.thumbnail)
#         file =cStringIO.StringIO(urllib.urlopen(self.thumbnail).read())
        img = Image.open(StringIO(response.content))
        img = img.resize((480,360), PIL.Image.ANTIALIAS)
        thumbnail_file = StringIO()
        img.save(thumbnail_file, 'JPEG',quality=40)
        thumbnail_file.seek(0)
        self.thumbnail_compressed.put(thumbnail_file,content_type = 'image/jpeg')
        self.thumbnail=server_url+"/get_image?id="+str(self.thumbnail_compressed.grid_id)
        self.url=self.info['src']
        self.type='playwire'
    def get_info(self):
        config=Template('http://cdn.playwire.com/v2/$publisher_id/config/$video_id.json')
        url=config.safe_substitute(publisher_id=self.publisher_id, video_id=self.video_id)
        p=urlopen(url)
        return json.loads(p.read())
    def to_dic(self):
        d=dict()
        d['video_id']=self.video_id
        d['publisher_id']=self.publisher_id
        d['type']='playwire'
        d['thumbnail']=self.thumbnail
        d['url']=self.url
        return d
    def __eq__(self,other):
        return self.url == other.url
    def __hash__(self):
        return hash(self.url)
class DailyMotion(Video):
    video_id=StringField()
    thumbnail=StringField()
    url=StringField()
    type=StringField()
    def init(self):
        url_template=Template('http://www.dailymotion.com/embed/video/$video_id')
        self.url=url_template.safe_substitute(video_id=self.video_id)
        self.thumbnail=self.get_thumbnail()
        self.type='dailymotion'
    def get_thumbnail(self):
        dailymotion_api=Template("https://api.dailymotion.com/video/$video_id?fields=thumbnail_large_url").safe_substitute(video_id=self.video_id)
        try:
            response=urlopen(dailymotion_api)
            info=json.loads(response.read())
            return info['thumbnail_large_url']
        except:
            return ""
    def to_dic(self):
        d=dict()
        d['video_id']=self.video_id
        d['type']='dailymotion'
        d['thumbnail']=self.thumbnail
        d['url']=self.url
        return d
    def __hash__(self):
        return hash(self.url)
    def __eq__(self,other):
        return self.url == other.url
# m=Main()
# s=m.fetch()
# print "x"
# m=Recommended("123") 
# m.fetch()
# p=Playwire(video_id="675354",publisher_id="16240")
# p.init()
# m=Main()
# main=m.fetch()
# s=Match(url=main[0].url)
# print s.url
# s.fetch()

# r=Recommended(device_id="my_device")
# r.fetch()
# m=Main()
# matches=m.fetch()
# m.save()
# for match in matches:
#     m=Match(url=match.url)
#     videos=m.fetch()
#     m.save()
#     print "match"
#     for video in videos:
#         print "video"
#         video.init()
#         print video.to_dic()